/*
 * REFREFFileDescriptorSet.h
 *
 *  Created on: May 12, 2013
 *      Author: Lucifer
 */

#ifndef __BFX_REFFILEDESCRIPTORSET_H__
#define __BFX_REFFILEDESCRIPTORSET_H__

#include <sys/types.h>

namespace BFX {

/**
 * This class represents a fd_set structure that's used by various berkerly sockets functions and service providers.
 */
class REFFileDescriptorSet : public REFObject
{
public:
	/**
	 * Initializes a new instance of BFX::REFREFFileDescriptorSet.
	 */
	REFFileDescriptorSet();
	/**
	 * Destroys the BFX::REFREFFileDescriptorSet instance.
	 */
	virtual ~REFFileDescriptorSet();

	/**
	 * Re-initializes the file descriptor set to contain no file descriptors.
	 */
	void Reset();
	/**
	 * Adds a file descriptor to a file descriptor set.
	 * @param The file descriptor.
	 * @return True if the function successful; otherwise false.
	 */
	bool Set(SOCKET fd);
	/**
	 * Gets a value indicates whether the file descriptor in the file descriptor set.
	 * @param fd The file descriptor.
	 * @return A value indicates whether the file descriptor in the file descriptor set.
	 */
	bool IsSet(SOCKET fd) const;

	/**
	 * Gets the pointer of the file descriptor set.
	 */
	operator fd_set*();
	/**
	 * Gets the max value of file descriptor in this file descriptor set.
	 * @return
	 */
	SOCKET GetMaxFileDescriptor() const;

private:
#ifdef	_WIN32
	// We use the "struct hack" to allow the number of descriptors to be varied at runtime.
	struct VARIED_FD_SET
	{
		u_int	fd_count;		// how many are SET?
		SOCKET	fd_array[1];	// pointer to first SOCKETs
	};
	VARIED_FD_SET*	m_pFdSet;
	UINT	m_nCapacity;
#else
	mutable fd_set	m_fdSet;	// the file descriptor set.
#endif
	SOCKET	m_fdMax;			// max value of file descriptor in this file descriptor set.
};

} /* namespace BFX */

#endif /* __BFX_REFFILEDESCRIPTORSET_H__ */
